package com.sam.chat.netty;

import com.alibaba.fastjson.JSONObject;
import com.sam.chat.utils.RedisKeyUtils;
import com.sam.chat.utils.RedisUtils;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.util.AttributeKey;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import static com.sam.chat.constants.ChatConstant.*;

/**
 * 操作执行类
 * <p>
 * TextWebSocketFrame类型,表示一个文本帧
 *
 * @author sam
 * @date 2021-12-22
 */
@Component
@ChannelHandler.Sharable
public class NettyHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {

    @Autowired
    private NettyHelper nettyHelper;
    @Autowired
    private RedisUtils redisUtils;


    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        super.handlerAdded(ctx);
        // NettyConfig.getChannelGroup().add(ctx.channel());
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) throws Exception {
        System.out.println("收到消息---->  " + msg.text());
        ReceiveBean receiveBean = JSONObject.parseObject(msg.text(), ReceiveBean.class);
        if (receiveBean != null) {
            if (NettyGroupManager.getUserChannelMap().get(receiveBean.getUserId()) != ctx.channel()) {
                NettyGroupManager.getUserChannelMap().put(receiveBean.getUserId(), ctx.channel());
                //将用户uid存入channel中，方便随时channel中取用户id
                AttributeKey<String> key = AttributeKey.valueOf("uid");
                ctx.channel().attr(key).setIfAbsent(receiveBean.getUserId());
                //回复成功
                nettyHelper.pushToUser(receiveBean.getUserId(), JSONObject.toJSONString(new ReceiveBean("0", receiveBean.getUserId(), 0,-1, "连接成功", "", "", "", "","","")));
                System.out.println("---->1");
            } else {
                System.out.println("---->2");
                nettyHelper.pushToUser(receiveBean.getToUid(), JSONObject.toJSONString(receiveBean));

                readOrUnread(receiveBean);
            }
        }


       /* System.out.println("收到消息---->  "+msg.text());
        JSONObject jsonObject = JSONObject.parseObject(msg.text());
        String uid = jsonObject.getString("uid");
        System.out.println("收到消息---->uid  "+uid);
        if (null != uid && !NettyConfig.getUserChannelMap().contains(uid)) {
            System.out.println("收到消息123---->  " + msg.text());
            NettyConfig.getUserChannelMap().put(uid, ctx.channel());
            //将用户uid存入channel中，方便随时channel中取用户id
            AttributeKey<String> key = AttributeKey.valueOf("uid");
            ctx.channel().attr(key).setIfAbsent(uid);
            //回复成功
            ctx.channel().writeAndFlush(new TextWebSocketFrame("服务器连接成功"));
        } else {
            // 前端定时请求,保持心跳连接,避免服务端误删通道
            // ctx.channel().writeAndFlush(new TextWebSocketFrame("keep alive success！"));
        }
        //前端定时请求,保持心跳连接,避免服务端误删通道
        if (null != jsonObject.getString("ping")) {
            JSONObject json = new JSONObject();
            json.put("pong", System.currentTimeMillis());
            ctx.channel().writeAndFlush(json);
        }*/
    }

    /**
     * 判读已读未读的redis逻辑
     */
    private void readOrUnread(ReceiveBean receiveBean) {
        //单聊的已读未读
        if (receiveBean.getRoomType() ==0){
            //标记已读未读
            //聊天界面id uid+&+toId uid/toId小的在前面
            try {
                if (null == receiveBean.getRoomId() || receiveBean.getRoomId().isEmpty()) {
                    return;
                }
                //有聊天进来，更新
                if (receiveBean.getType() == 1) {
                    //app端首页roomList的插入,更新，只存一条
                    redisUtils.insertHash(
                            RedisKeyUtils.getRedisSingleRoomListKey(receiveBean.getUserId()),
                            receiveBean.getRoomId(),
                            receiveBean);
                    redisUtils.insertHash(
                            RedisKeyUtils.getRedisSingleRoomListKey(receiveBean.getToUid()),
                            receiveBean.getRoomId(),
                            receiveBean);
                    //标记未读
                    redisUtils.insertHash(
                            RedisKeyUtils.getRedisUnReadKey(receiveBean.getRoomId(), receiveBean.getToUid()),
                            receiveBean.getMessageId(),
                            receiveBean);
                }

                if (receiveBean.getType() == 0 && CHAT_READ_ACK.equals(receiveBean.getMessage())) {
                    //删除已读
                    redisUtils.del(RedisKeyUtils.getRedisUnReadKey(receiveBean.getRoomId(), receiveBean.getUserId()));
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }else if (receiveBean.getRoomType() ==1){
            //群聊

            if (null == receiveBean.getRoomId() || receiveBean.getRoomId().isEmpty()) {
                return;
            }

            //有聊天进来，更新
            if (receiveBean.getType() == 1) {
                //app端首页roomList的插入,更新，只存一条
                redisUtils.insertHash(
                        RedisKeyUtils.getRedisGroupRoomListKey(receiveBean.getUserId()),
                        receiveBean.getRoomId(),
                        receiveBean.getMessageId());
                redisUtils.insertHash(
                        RedisKeyUtils.getRedisGroupRoomListKey(receiveBean.getToUid()),
                        receiveBean.getRoomId(),
                        receiveBean.getMessageId());
                //标记未读
                redisUtils.insertHash(
                        RedisKeyUtils.getRedisUnReadKey(receiveBean.getRoomId(), receiveBean.getToUid()),
                        receiveBean.getMessageId(),"");
                //存入消息()
                redisUtils.setIfAbsent(RedisKeyUtils.getGroupInKey(receiveBean.getMessageId()),receiveBean,3600*24*30);
            }

            if (receiveBean.getType() == 0 && CHAT_READ_ACK.equals(receiveBean.getMessage())) {
                //删除已读
                redisUtils.del(RedisKeyUtils.getRedisUnReadKey(receiveBean.getRoomId(), receiveBean.getUserId()));
            }

        }

    }

    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
        super.handlerRemoved(ctx);
        remove(ctx);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        super.exceptionCaught(ctx, cause);
        System.out.println("错误异常" + cause.getMessage());
        remove(ctx);
    }

    private void remove(ChannelHandlerContext ctx) {
        try {
            //删除通道
            NettyGroupManager.getChannelGroup().remove(ctx.channel());
            //删除用户与channel对应关系
            AttributeKey<String> key = AttributeKey.valueOf("uid");
            String uid = ctx.channel().attr(key).get();
            if (NettyGroupManager.getUserChannelMap() != null && uid != null) {
                NettyGroupManager.getUserChannelMap().remove(uid);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
